package com.yt.server.scheduling;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.atomic.AtomicLong;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.SimpleTrigger;
import org.quartz.Trigger;
import org.quartz.impl.StdSchedulerFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import com.yt.server.Scope;
import com.yt.server.api.scheduling.IScheduledJob;
import com.yt.server.api.scheduling.ISchedulingService;

/**
 * @author 刘晶 
 * Quartz任务调度
 */
public class QuartzSchedulingService implements ISchedulingService,
		InitializingBean, DisposableBean {

	protected static Logger log = LoggerFactory.getLogger(Scope.class);

	protected AtomicLong jobDetailCounter = new AtomicLong(0);

	protected SchedulerFactory factory;

	protected Scheduler scheduler;

	protected String instanceId;

	public void afterPropertiesSet() throws Exception {
		log.debug("初始化...");
		try {
			if (factory == null) {
				factory = new StdSchedulerFactory();
			}
			if (instanceId == null) {
				scheduler = factory.getScheduler();
			} else {
				scheduler = factory.getScheduler(instanceId);
			}
			if (scheduler != null) {
				scheduler.start();
			} else {
				log.error("调度程序尚未启动");
			}
		} catch (SchedulerException ex) {
			throw new RuntimeException(ex);
		}
	}

	public void setFactory(SchedulerFactory factory) {
		this.factory = factory;
	}

	public void setInstanceId(String instanceId) {
		this.instanceId = instanceId;
	}

	public String addScheduledJob(int interval, IScheduledJob job) {
		String result = getJobName();
		SimpleTrigger trigger = new SimpleTrigger("Trigger_" + result, null,
				new Date(), null, SimpleTrigger.REPEAT_INDEFINITELY, interval);
		scheduleJob(result, trigger, job);
		return result;
	}

	public String addScheduledOnceJob(Date date, IScheduledJob job) {
		String result = getJobName();

		SimpleTrigger trigger = new SimpleTrigger("Trigger_" + result, null,
				date);
		scheduleJob(result, trigger, job);
		return result;
	}

	public String addScheduledOnceJob(long timeDelta, IScheduledJob job) {
		return addScheduledOnceJob(new Date(System.currentTimeMillis()
				+ timeDelta), job);
	}

	public String addScheduledJobAfterDelay(int interval, IScheduledJob job,
			int delay) {
		String result = getJobName();
		long startTime = System.currentTimeMillis() + delay;
		SimpleTrigger trigger = new SimpleTrigger("Trigger_" + result, null,
				new Date(startTime), null, SimpleTrigger.REPEAT_INDEFINITELY,
				interval);
		scheduleJob(result, trigger, job);
		return result;
	}

	public String getJobName() {
		String result = "ScheduledJob_" + jobDetailCounter.getAndIncrement();
		return result;
	}

	public List<String> getScheduledJobNames() {
		List<String> result = new ArrayList<String>();
		if (scheduler != null) {
			try {
				for (String name : scheduler.getJobNames(null)) {
					result.add(name);
				}
			} catch (SchedulerException ex) {
				throw new RuntimeException(ex);
			}
		} else {
			log.warn("没有调度");
		}
		return result;
	}

	public void pauseScheduledJob(String name) {
		try {
			scheduler.pauseJob(name, null);
		} catch (SchedulerException ex) {
			throw new RuntimeException(ex);
		}
	}

	public void resumeScheduledJob(String name) {
		try {
			scheduler.resumeJob(name, null);
		} catch (SchedulerException ex) {
			throw new RuntimeException(ex);
		}
	}

	public void pauseScheduledTrigger(String name) {
		try {
			scheduler.pauseTrigger("Trigger_" + name, null);
		} catch (SchedulerException ex) {
			throw new RuntimeException(ex);
		}
	}

	public void resumeScheduledTrigger(String name) {
		try {
			scheduler.resumeTrigger("Trigger_" + name, null);
		} catch (SchedulerException ex) {
			throw new RuntimeException(ex);
		}
	}

	public void removeScheduledJob(String name) {
		try {
			scheduler.deleteJob(name, null);
		} catch (SchedulerException ex) {
			throw new RuntimeException(ex);
		}
	}

	private void scheduleJob(String name, Trigger trigger, IScheduledJob job) {
		if (scheduler != null) {
			JobDetail jobDetail = new JobDetail(name, null,
					QuartzSchedulingServiceJob.class);
			jobDetail.getJobDataMap().put(
					QuartzSchedulingServiceJob.SCHEDULING_SERVICE, this);
			jobDetail.getJobDataMap().put(
					QuartzSchedulingServiceJob.SCHEDULED_JOB, job);
			try {
				scheduler.scheduleJob(jobDetail, trigger);
			} catch (SchedulerException ex) {
				throw new RuntimeException(ex);
			}
		} else {
			log.warn("没有调度");
		}
	}

	public void destroy() throws Exception {
		if (scheduler != null) {
			log.debug("销毁...");
			scheduler.shutdown();
		}
	}
}